from neuro.exceptions import BaseException
from neuro.exceptions import IllegalArgumentException

def matrix_iq(raw_score, age, edu_years, race, ethnicity, region, gender):
	'''
	Calculate estimated IQ from Matrix Reasoning ::
	
		>>> from neuro.psych.formulas import matrix_iq, Race, Ethnicity, Region, Gender
		>>> matrix_iq(24, 24, 16, Race.OTHER, Ethnicity.NOT_HISPANIC_LATINO, Region.NORTH_EAST, Gender.MALE)
		120.373
		
	:param raw_score: Matrix Reasoning raw score
	:type raw_score: float
	:param age: Age
	:type age: int
	:param edu_years: Years of education
	:type edu_years: int
	:param race: :class:`Race.BLACK_AA`, :class:`Race.WHITE`, :class:`Race.OTHER`
	:type race: str
	:param ethnicity: :class:`Ethnicity.HISPANIC_LATINO`, :class:`Ethnicity.NOT_HISPANIC_LATINO`
	:type ethnicity: int
	:param region: :class:`Region.SOUTH`, :class:`Region.NORTH_CENTRAL`, :class:`Region.NORTH_EAST`, :class:`Region.WEST`
	:type region: int
	:param gender: :class:`Gender.MALE`, :class:`Gender.FEMALE`
	:type gender: int
	:returns: Estimated IQ
	:rtype: float
	:raises: :class:`MatrixRaceEthnException`, :class:`MatrixRawScoreException`
	:citation: Schoenberg, M.R., Scott, J.G., Duff, K. & Adams R.L. (2002). Estimation of WAIS-III Intelligence from Combined Performance and Demographic Variables: Development of the OPIE-3. *Clin. Neuropsychol.*, *16*: 426-438.
	'''
	edu_cat = None
	race_ethn_cat = None
	
	if not isinstance(raw_score, (int, float, long)):
		raise IllegalArgumentException("Matrix raw score must be numeric")
	elif raw_score < 0:
		raise IllegalArgumentException("Matrix raw score must be a positive integer")
	elif raw_score > 26:
		raise MatrixRawScoreException(MatrixRawScoreException.TOO_LARGE, raw_score)
	
	if not isinstance(age, int):
		raise IllegalArgumentException("Age must be an integer")
	elif age < 0:
		raise IllegalArgumentException("Age must be a positive integer")
	
	if not isinstance(edu_years, int):
		raise IllegalArgumentException("Education must be an integer")
	elif edu_years < 0:
		raise IllegalArgumentException("Education must be a positive integer")	
	
	## --- education category
	if(edu_years >= 0 and edu_years <= 8):
		edu_cat = 1
	elif(edu_years >= 9 and edu_years <= 11):
		edu_cat = 2
	elif(edu_years == 12):
		edu_cat = 3
	elif(edu_years >= 13 and edu_years <= 15):
		edu_cat = 4
	elif(edu_years >= 16):
		edu_cat = 5
	
	## --- race/ethnicity category
	if race == Race.BLACK_AA:
		if ethnicity == Ethnicity.HISPANIC_LATINO:
			race_ethn_cat = 2
		elif ethnicity == Ethnicity.NOT_HISPANIC_LATINO:
			race_ethn_cat = 1
		else:
			raise MatrixRaceEthnException(MatrixRaceEthnException.UNKNOWN_ETHNICITY)
	elif race == Race.WHITE:
		if ethnicity == Ethnicity.HISPANIC_LATINO:
			race_ethn_cat = 2
		elif ethnicity == Ethnicity.NOT_HISPANIC_LATINO:
			race_ethn_cat = 4
		else:
			raise MatrixIQException(MatrixRaceEthnException.UNKNOWN_ETHNICITY)
	elif race == Race.OTHER:
		if ethnicity == Ethnicity.HISPANIC_LATINO:
			race_ethn_cat = 2
		elif ethnicity == Ethnicity.NOT_HISPANIC_LATINO:
			race_ethn_cat = 3
		else:
			raise MatrixRaceEthnException(MatrixRaceEthnException.UNKNOWN_ETHNICITY)
	else:
		MatrixRaceEthnException(MatrixRaceEthnException.UNKNOWN_RACE)
	
	## --- convert Matrix raw score to IQ estimate
	return (43.678 + (raw_score * 1.943) + (age * 0.297) + (edu_cat * 3.564) + (race_ethn_cat * 1.541) + (region * 0.543) - (gender * 1.137))
	
def shipley_iq(age, raw_score):
	'''
	Calculate estimated IQ from Shipley (16 <= age <= 64)::
	
		>>> from neuro.psych.formulas import shipley_iq
		>>> shipley_iq(64, 37)
		124.0
	
	:param age: Age
	:type age: int
	:param raw_score: Raw Shipley score
	:type raw_score: int, float
	:returns: Extimated IQ
	:rtype: float
	:raises: :class:`ShipleyAgeException`, :class:`ShipleyRawScoreException`
	:citation: Paulson, M.J. & Lin, T.-T. (1970). Predicting WAIS IQ from Shipley-Hartford Scores. *J. Clin. Psychol.*, *26*: 1-9.
	'''
	if not isinstance(age, int):
		raise IllegalArgumentException("Age must be an int")
	elif age < 0:
		raise IllegalArgumentException("Age cannot be negative")
	elif not isinstance(raw_score, (int, float, long)):
		raise IllegalArgumentException("Raw score must be numeric")
	elif raw_score < 0:
		raise IllegalArgumentException("Raw score cannot be negative")
	
	ages = SHIPLEY_A1[0]
	
	## --- raw score lookup is int based
	if isinstance(raw_score, (float, long)):
		raw_score = int(round(raw_score))
	
	if raw_score > 40:
		raise ShipleyRawScoreException(ShipleyRawScoreException.TOO_LARGE, raw_score)
	
	keep_row = None
	for row in SHIPLEY_A1:
		if row[0] == raw_score:
			keep_row = row
			break
	
	try:
		index = ages.index(age)
	except ValueError, e:
		raise ShipleyAgeException(ShipleyAgeException.CANNOT_FIND, age)
	
	## --- convert t-score to IQ estimate using Shipley Table A-1
	tscore = keep_row[index]
	return ((((float(tscore) - 50) / 10) * 15) + 100)

class Gender:
	'''
	Gender constants
	'''
	MALE=1
	FEMALE=2

class Race:
	'''
	Race constants
	'''
	BLACK_AA=1
	WHITE=2
	OTHER=3

class Ethnicity:
	'''
	Ethnicity constants
	'''
	HISPANIC_LATINO=1
	NOT_HISPANIC_LATINO=2

class Region:
	'''
	Region constants
	'''
	SOUTH=1
	NORTH_CENTRAL=2
	NORTH_EAST=3
	WEST=4

class MatrixRawScoreException(BaseException):
	'''
	Matrix raw score exception
	'''
	TOO_SMALL=1
	TOO_LARGE=2
	
	def __init__(self, code, score):
		'''
		Constructor
		
		:param code: Code
		:type code: int
		:param score: Matrix raw score
		:type score: int, float, long
		'''
		self._code = code
		self._score = score
		
	def getMessage(self):
		'''
		Get custom message

		:rtype: str
		'''
		if self._code == MatrixRawScoreException.TOO_LARGE:
			return "Matrix raw score is too large: " + str(self._score)
		elif self._code == MatrixRawScoreException.TOO_SMALL:
			return "Matrix raw score is too small: " + str(self._score)
	
class ShipleyAgeException(BaseException):
	'''
	Shipley age exception
	'''
	CANNOT_FIND=1

	def __init__(self, code, age):
		'''
		Constructor
		
		:param code: Code
		:type code: int
		:param age: Age
		:type age: int
		'''
		BaseException.__init__(self)

		if not isinstance(code, int):
			raise IllegalArgumentException("Code must be an int")
		elif not isinstance(age, int):
			raise IllegalArgumentException("Age must be an int")
		
		self._code = code
		self._age = age

	def getMessage(self):
		'''
		Get custom message

		:rtype: str
		'''
		if self._code == ShipleyAgeException.CANNOT_FIND:
			return "Cannot find age in Shipley A1 table: " + str(self._age)

class ShipleyRawScoreException(BaseException):
	'''
	Shipley raw score exception
	'''
	TOO_LARGE=1

	def __init__(self, code, score):
		'''
		Constructor
		
		:param code: ShipleyRawScoreException.TOO_LARGE, etc.
		:type code: int
		:param age: Score
		:type age: int
		'''
		BaseException.__init__(self)
		
		if not isinstance(code, int):
			raise IllegalArgumentException("Code must be an int")
		elif not isinstance(score, int):
			raise IllegalArgumentException("Score must be an int")
		
		self._code = code
		self._score = score

	def getMessage(self):
		'''
		Get custom message

		:rtype: str
		'''
		if self._code == ShipleyRawScoreException.TOO_LARGE:
			return "Score is too large " + str(self._score)
		
class MatrixRaceEthnException(BaseException):
	'''
	Matrix race/ethnicity exception
	'''
	UNKNOWN_RACE=1
	UNKNOWN_ETHNICITY=2

	def __init__(self, code, val):
		'''
		Constructor
		
		:param code: MatrixRaceEthnException.UNKNOWN_RACE, etc.
		:type code: int
		:param age: Value
		:type age: int
		'''
		BaseException.__init__(self)
		
		if not isinstance(code, int):
			raise IllegalArgumentException("Code must be an int")
		elif not isinstance(score, int):
			raise IllegalArgumentException("Score must be an int")
		
		self._code = code
		self._val = val

	def getMessage(self):
		'''
		Get custom message

		:rtype: str
		'''
		if self._code == MatrixRaceEthnException.UNKNOWN_RACE:
			return "Unknown race: " + str(self._val)
		elif self._code == MatrixRaceEthnException.UNKNOWN_ETHNICITY:
			return "Unknown ethnicity: " + str(self._val)
	
SHIPLEY_A1 = \
[[-1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64],
 [0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
 [1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
 [2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
 [3, 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
 [4, 12, 12, 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
 [5, 13, 13, 12, 12, 10, 10, 10, 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 10, 10, 10, 10],
 [6, 15, 15, 14, 14, 12, 12, 12, 12, 12, 10, 10, 10, 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 12, 12, 12, 12],
 [7, 17, 17, 16, 16, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 11, 11, 11, 11, 13, 13, 13, 13, 13],
 [8, 19, 19, 17, 17, 16, 16, 16, 16, 16, 13, 13, 13, 13, 13, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15],
 [9, 20, 20, 19, 19, 17, 17, 17, 17, 17, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 17, 17, 17, 17, 17],
 [10, 22, 22, 21, 21, 19, 19, 19, 19, 19, 17, 17, 17, 17, 17, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 19, 19, 19, 19, 19],
 [11, 24, 24, 23, 23, 21, 21, 21, 21, 21, 18, 18, 18, 18, 18, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 20, 20, 20, 20, 20],
 [12, 26, 26, 24, 24, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 20, 20, 20, 20, 20, 22, 22, 22, 22, 22],
 [13, 27, 27, 26, 26, 24, 24, 24, 24, 24, 22, 22, 22, 22, 22, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 24, 24, 24, 24, 24],
 [14, 29, 29, 28, 28, 26, 26, 26, 26, 26, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 26, 26, 26, 26, 26],
 [15, 31, 31, 30, 30, 28, 28, 28, 28, 28, 25, 25, 25, 25, 25, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27],
 [16, 33, 33, 31, 31, 29, 29, 29, 29, 29, 27, 27, 27, 27, 27, 25, 25, 25, 25, 25, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29],
 [17, 34, 34, 33, 33, 31, 31, 31, 31, 31, 29, 29, 29, 29, 29, 27, 27, 27, 27, 27, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 31, 31, 31, 31, 31],
 [18, 36, 36, 35, 35, 33, 33, 33, 33, 33, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 30, 32, 32, 32, 32, 32],
 [19, 38, 38, 37, 37, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34],
 [20, 40, 40, 38, 38, 36, 36, 36, 36, 36, 34, 34, 34, 34, 34, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 34, 34, 34, 34, 34, 36, 36, 36, 36, 36],
 [21, 41, 41, 40, 40, 38, 38, 38, 38, 38, 36, 36, 36, 36, 36, 34, 34, 34, 34, 34, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 38, 38, 38, 38, 38],
 [22, 43, 43, 42, 42, 40, 40, 40, 40, 40, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 37, 37, 37, 37, 37, 39, 39, 39, 39, 39],
 [23, 45, 45, 44, 44, 42, 42, 42, 42, 42, 39, 39, 39, 39, 39, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 39, 39, 39, 39, 39, 41, 41, 41, 41, 41],
 [24, 47, 47, 45, 45, 43, 43, 43, 43, 43, 41, 41, 41, 41, 41, 39, 39, 39, 39, 39, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43],
 [25, 48, 48, 47, 47, 45, 45, 45, 45, 45, 43, 43, 43, 43, 43, 41, 41, 41, 41, 41, 40, 40, 40, 40, 40, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 45, 45, 45, 45, 45],
 [26, 50, 50, 49, 49, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 42, 42, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, 46, 46, 46, 46, 46],
 [27, 52, 52, 51, 51, 49, 49, 49, 49, 49, 46, 46, 46, 46, 46, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 46, 46, 46, 46, 46, 48, 48, 48, 48, 48],
 [28, 54, 54, 52, 52, 50, 50, 50, 50, 50, 48, 48, 48, 48, 48, 46, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 48, 48, 48, 48, 48, 50, 50, 50, 50, 50],
 [29, 55, 55, 54, 54, 52, 52, 52, 52, 52, 50, 50, 50, 50, 50, 48, 48, 48, 48, 48, 47, 47, 47, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 52, 52, 52, 52, 52],
 [30, 57, 57, 56, 56, 54, 54, 54, 54, 54, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 49, 49, 49, 49, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 51, 51, 51, 51, 51, 53, 53, 53, 53, 53],
 [31, 59, 59, 58, 58, 56, 56, 56, 56, 56, 53, 53, 53, 53, 53, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 53, 53, 53, 53, 53, 55, 55, 55, 55, 55],
 [32, 61, 61, 59, 59, 57, 57, 57, 57, 57, 55, 55, 55, 55, 55, 53, 53, 53, 53, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 55, 55, 55, 55, 55, 57, 57, 57, 57, 57],
 [33, 62, 62, 61, 61, 59, 59, 59, 59, 59, 57, 57, 57, 57, 57, 55, 55, 55, 55, 55, 54, 54, 54, 54, 54, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 59, 59, 59, 59, 59],
 [34, 64, 64, 63, 63, 61, 61, 61, 61, 61, 58, 58, 58, 58, 58, 57, 57, 57, 57, 57, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 58, 58, 58, 58, 58, 60, 60, 60, 60, 60],
 [35, 66, 66, 65, 65, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 58, 58, 58, 58, 58, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 60, 60, 60, 60, 60, 62, 62, 62, 62, 62],
 [36, 68, 68, 66, 66, 64, 64, 64, 64, 64, 62, 62, 62, 62, 62, 60, 60, 60, 60, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 62, 62, 62, 62, 62, 64, 64, 64, 64, 64],
 [37, 69, 69, 68, 68, 66, 66, 66, 66, 66, 64, 64, 64, 64, 64, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66],
 [38, 71, 71, 70, 70, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 64, 64, 64, 64, 64, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67],
 [39, 73, 73, 71, 71, 70, 70, 70, 70, 70, 67, 67, 67, 67, 67, 65, 65, 65, 65, 65, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 69, 69, 69, 69, 69],
 [40, 75, 75, 73, 73, 71, 71, 71, 71, 71, 69, 69, 69, 69, 69, 67, 67, 67, 67, 67, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 69, 69, 69, 69, 69, 71, 71, 71, 71, 71]]
